﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using HAOest.Forms.Mouse;

namespace HAOest.Forms.Forms
{
    /// <summary>
    /// Win8Form窗体类
    /// <para>作者：邓斌HADB</para>
    /// </summary>
    public partial class Win8Form : BlankForm
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public Win8Form()
        {
            InitializeComponent();
        }

        #region 声明变量和常量

        private String formName = null;                 //窗口名
        private Image formIconImage = null;             //窗口图标
        private int resizeBorderThickness = 2;          //拉伸时边框宽度
        private int formBorderThickness = 2;            //窗体边框宽度
        private Color mainmenuBackColor = Color.Empty;  //菜单背景色
        private Color titleBackColor = Color.Empty;     //标题栏背景色
        private Color topBackColor = Color.Empty;       //顶部背景色
        private Color formBackColor = Color.Empty;      //窗体背景色
        private Color formBorderColor = Color.Empty;    //窗体边框颜色
        private MenuStrip defaultMenuStrip = null;      //主菜单
        private MouseAction mouse = null;               //鼠标，用来改变鼠标形状
        #endregion

        #region 属性设置
        /// <summary>
        /// 菜单栏背景
        /// </summary>
        [Browsable(true)]
        [Description("菜单栏背景颜色")]
        [Category("Win8Form")]
        public Color MainMenuBackColor
        {
            get
            {
                if (mainmenuBackColor == Color.Empty) mainmenuBackColor = Color.Transparent;
                return mainmenuBackColor;
            }
            set
            {
                mainmenuBackColor = value;
                MainMenuStrip.BackColor = mainmenuBackColor;
            }
        }

        /// <summary>
        /// 标题栏背景
        /// </summary>
        [Browsable(true)]
        [Description("标题栏背景颜色")]
        [Category("Win8Form")]
        public Color TitleBackColor
        {
            get
            {
                if (titleBackColor == Color.Empty) titleBackColor = Color.Transparent;
                return titleBackColor;
            }
            set
            {
                titleBackColor = value;
                LabelWindowName.BackColor = titleBackColor;
            }
        }

        /// <summary>
        /// 顶部背景
        /// </summary>
        [Browsable(true)]
        [Description("顶部背景颜色")]
        [Category("Win8Form")]
        public Color TopBackColor
        {
            get
            {
                if (topBackColor == Color.Empty) topBackColor = Color.Transparent;
                return topBackColor;
            }
            set
            {
                topBackColor = value;
                TableLayoutPanelTop.BackColor = topBackColor;
            }
        }

        /// <summary>
        /// 窗体背景
        /// </summary>
        [Browsable(true)]
        [Description("窗体背景颜色")]
        [Category("Win8Form")]
        public Color FormBackColor
        {
            get
            {
                if (formBackColor == Color.Empty) formBackColor = Color.WhiteSmoke;
                return formBackColor;
            }
            set
            {
                formBackColor = value;
                if (formBackColor == Color.Empty) formBackColor = Color.WhiteSmoke;
                MainPanel.BackColor = formBackColor;
            }
        }

        /// <summary>
        /// 窗体边框颜色
        /// </summary>
        [Browsable(true)]
        [Description("窗体边框颜色")]
        [Category("Win8Form")]
        public Color FormBorderColor
        {
            get
            {
                if (formBorderColor == Color.Empty) formBorderColor = Color.DodgerBlue;
                return formBorderColor;
            }
            set
            {
                formBorderColor = value;
                if (formBorderColor == Color.Empty) formBorderColor = Color.DodgerBlue;
                this.BackColor = formBorderColor;
            }
        }

        /// <summary>
        /// 窗体边框粗细
        /// </summary>
        [Browsable(true)]
        [Description("窗体边框粗细")]
        [Category("Win8Form")]
        public int FormBorderThickness
        {
            get
            {
                return formBorderThickness;
            }
            set
            {
                formBorderThickness = value;
                this.Padding = new Padding(formBorderThickness);
            }
        }

        /// <summary>
        /// 主菜单
        /// </summary>
        [Browsable(true)]
        [TypeConverter(typeof(ReferenceConverter))]
        [Description("窗口主菜单")]
        [Category("Win8Form")]
        public new MenuStrip MainMenuStrip
        {

            get
            {
                return defaultMenuStrip;
            }
            set
            {
                defaultMenuStrip = value;
                defaultMenuStrip.BackColor = MainMenuBackColor;
                TableLayoutPanelTop.Controls.Add(defaultMenuStrip, 1, 1);
                defaultMenuStrip.Refresh();
            }
        }

        /// <summary>
        /// 窗口图标
        /// </summary>
        [Browsable(true)]
        [Description("窗口图标")]
        [Category("Win8Form")]
        public Image FormIconImage
        {
            get
            {
                if (formIconImage == null)
                    formIconImage = PictureBoxIcon.Image;//赋初始值
                return formIconImage;
            }
            set
            {
                formIconImage = value;
                PictureBoxIcon.Image = formIconImage;
            }
        }

        /// <summary>
        /// 窗口名
        /// </summary>
        [Browsable(true)]
        [Description("窗口名")]
        public override String Text
        {
            get
            {
                if (formName == null) formName = "HAOestForm";
                return formName;
            }
            set
            {
                formName = value;
                LabelWindowName.Text = formName;
            }
        }

        /// <summary>
        /// 隐藏背景色属性
        /// </summary>
        [Browsable(false)]
        public override Color BackColor
        {
            get
            {
                return base.BackColor;
            }
            set
            {
                base.BackColor = value;
            }
        }
        #endregion

        #region 事件：最小化、最大化、关闭




        /// <summary>
        /// 双击标题栏
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void LabelWindowName_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (this.FindForm().WindowState == FormWindowState.Normal)
            {
                this.FindForm().WindowState = FormWindowState.Maximized;
                Invalidate();
            }
            else if (this.FindForm().WindowState == FormWindowState.Maximized)
            {
                this.FindForm().WindowState = FormWindowState.Normal;
                Invalidate();
            }
        }



        #endregion

        #region 事件：移动窗口
        private void LabelWindowName_MouseDown(object sender, MouseEventArgs e)
        {
            mouse = new MouseDrag(this.FindForm());
        }

        private void LabelWindowName_MouseUp(object sender, MouseEventArgs e)
        {
            mouse = null;
        }

        private void LabelWindowName_MouseMove(object sender, MouseEventArgs e)
        {
            SetCursor();
            if ((e.Button == MouseButtons.Left) && (mouse != null))
            {
                mouse.Action(this.FindForm());
            }
        }
        #endregion

        #region 事件：调整窗口大小
        /*
        private void FormContainer_MouseDown(object sender, MouseEventArgs e)
        {
            int left = this.FindForm().Left;
            int top = this.FindForm().Top;

            if (Functions.GetMousePosition().X <= left + resizeBorderThickness)
                mouse = new MouseSizeLeft();
            else if (Functions.GetMousePosition().X >= left + Width - 2 - resizeBorderThickness)
                mouse = new MouseSizeRight();
            else if (Functions.GetMousePosition().Y <= top + resizeBorderThickness)
                mouse = new MouseSizeTop();
            else if (Functions.GetMousePosition().Y >= top + Height - 2 - resizeBorderThickness)
                mouse = new MouseSizeBottom();
        }

        private void FormContainer_MouseMove(object sender, MouseEventArgs e)
        {
            if (CheckForReSize() && (e.Button == MouseButtons.Left))
            {
                mouse.Action(this.FindForm());
            }
        }

        private void TableLayoutPanelTop_MouseMove(object sender, MouseEventArgs e)
        {
            CheckForReSize();
        }

        private void ButtonMin_MouseMove(object sender, MouseEventArgs e)
        {
            CheckForReSize();
        }

        private void ButtonMax_MouseMove(object sender, MouseEventArgs e)
        {
            CheckForReSize();
        }

        private void ButtonClose_MouseMove(object sender, MouseEventArgs e)
        {
            CheckForReSize();
        }

        /// <summary>
        /// 改变鼠标形状，调整窗口大小
        /// </summary>
        private bool CheckForReSize()
        {
            SetCursor();
            if (mouse != null)
            {
                mouse.Action(this.FindForm());//执行事件响应
                return true;
            }
            else return false;
        }

        private void FormContainer_MouseUp(object sender, MouseEventArgs e)
        {
            mouse = null;
        }
        */
        [DllImport("user32.dll ", EntryPoint = "SendMessage ")]
        public static extern int SendMessage(int hWnd, int wMsg, int wParam, int lParam);
        [DllImport("user32.dll ", EntryPoint = "ReleaseCapture ")]
        public static extern int ReleaseCapture();
        public const int WM_SYSCOMMAND = 0x0112;
        public const int SC_MOVE = 0xF012;
        bool _canResize = true;

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == Win32.WM_NCPAINT)
            {
                return;
            }
            else if (m.Msg == Win32.WM_NCCALCSIZE)
            {
                return;
            }
            else if (m.Msg == Win32.WM_NCACTIVATE)
            {
                if (m.WParam == (IntPtr)Win32.WM_FALSE)
                {
                    m.Result = (IntPtr)Win32.WM_TRUE;
                }
            }
            else if (m.Msg == Win32.WM_NCHITTEST)
            {
                if (_canResize == true)
                {
                    Point point = new Point(m.LParam.ToInt32());
                    int x = point.X;
                    int y = point.Y;
                    if (x < this.Left + 11 && y < this.Top + 11)
                    {
                        m.Result = (IntPtr)Win32.HTTOPLEFT;
                    }
                    else if (x > this.Right - 11 && y < this.Top + 11)
                    {
                        m.Result = (IntPtr)Win32.HTTOPRIGHT;
                    }
                    else if (x > this.Right - 11 && y > this.Bottom - 11)
                    {
                        m.Result = (IntPtr)Win32.HTBOTTOMRIGHT;
                    }
                    else if (x < this.Left + 11 && y > this.Bottom - 11)
                    {
                        m.Result = (IntPtr)Win32.HTBOTTOMLEFT;
                    }
                    else if (x < this.Left + 9)
                    {
                        m.Result = (IntPtr)Win32.HTLEFT;
                    }
                    else if (y < this.Top + 9)
                    {
                        m.Result = (IntPtr)Win32.HTTOP;
                    }
                    else if (x > this.Right - 9)
                    {
                        m.Result = (IntPtr)Win32.HTRIGHT;
                    }
                    else if (y > this.Bottom - 9)
                    {
                        m.Result = (IntPtr)Win32.HTBOTTOM;
                    }
                    else
                    {
                        m.Result = (IntPtr)Win32.HTCAPTION;
                    }
                }
                else
                {
                    //m.Result = (IntPtr)Win32.HTCAPTION;
                    ReleaseCapture();
                    SendMessage(this.Handle.ToInt32(), WM_SYSCOMMAND, SC_MOVE + Win32.HTCAPTION, 0);
                }
            }
            else
                base.WndProc(ref m);
        }

        private static class Win32
        {
            public const int MF_REMOVE = 0x1000;

            public const int SC_RESTORE = 0xF120; //还原
            public const int SC_MOVE = 0xF010; //移动
            public const int SC_SIZE = 0xF000; //大小
            public const int SC_MINIMIZE = 0xF020; //最小化
            public const int SC_MAXIMIZE = 0xF030; //最大化
            public const int SC_CLOSE = 0xF060; //关闭 

            public const int WM_SYSCOMMAND = 0x0112;
            public const int WM_COMMAND = 0x0111;

            public const int GW_HWNDFIRST = 0;
            public const int GW_HWNDLAST = 1;
            public const int GW_HWNDNEXT = 2;
            public const int GW_HWNDPREV = 3;
            public const int GW_OWNER = 4;
            public const int GW_CHILD = 5;

            public const int WM_LBUTTONDOWN = 0x0201;
            public const int WM_LBUTTONUP = 0x0202;
            public const int WM_LBUTTONDBLCLK = 0x0203;
            public const int WM_WINDOWPOSCHANGING = 0x46;
            public const int WM_PAINT = 0xF;
            public const int WM_CREATE = 0x0001;
            public const int WM_ACTIVATE = 0x0006;
            public const int WM_NCCREATE = 0x0081;
            public const int WM_NCCALCSIZE = 0x0083;
            public const int WM_NCPAINT = 0x0085;
            public const int WM_NCACTIVATE = 0x0086;
            public const int WM_NCLBUTTONDOWN = 0x00A1;
            public const int WM_NCLBUTTONUP = 0x00A2;
            public const int WM_NCLBUTTONDBLCLK = 0x00A3;
            public const int WM_NCMOUSEMOVE = 0x00A0;

            public const int WM_PRINT = 0x317;
            public const int WM_DESTROY = 0x2;
            public const int WM_SHOWWINDOW = 0x18;
            public const int WM_SHARED_MENU = 0x1E2;
            public const int HC_ACTION = 0;
            public const int WH_CALLWNDPROC = 4;
            public const int GWL_WNDPROC = -4;
            public const int WM_NCHITTEST = 0x0084;

            public const int HTLEFT = 10;
            public const int HTRIGHT = 11;
            public const int HTTOP = 12;
            public const int HTTOPLEFT = 13;
            public const int HTTOPRIGHT = 14;
            public const int HTBOTTOM = 15;
            public const int HTBOTTOMLEFT = 0x10;
            public const int HTBOTTOMRIGHT = 17;
            public const int HTCAPTION = 2;

            public const int WS_SYSMENU = 0x80000;
            public const int WS_SIZEBOX = 0x40000;

            public const int WS_MAXIMIZEBOX = 0x10000;

            public const int WS_MINIMIZEBOX = 0x20000;

            public const int WM_FALSE = 0;
            public const int WM_TRUE = 1;

            public const int CS_DROPSHADOW = 0x20000;

            public const int GCW_ATOM = -32;
            public const int GCL_CBCLSEXTRA = -20;
            public const int GCL_CBWNDEXTRA = -18;
            public const int GCL_HBRBACKGROUND = -10;
            public const int GCL_HCURSOR = -12;
            public const int GCL_HICON = -14;
            public const int GCL_HMODULE = -16;
            public const int GCL_MENUNAME = -8;
            public const int GCL_STYLE = -26;
            public const int GCL_WNDPROC = -24;
        }
        #endregion


        #region 公共方法
        /// <summary>
        /// 检查鼠标类型
        /// </summary>
        /// <param name="point">鼠标位置</param>
        /// <returns></returns>
        private Cursor CheckCursorType(Point point)
        {
            int top = this.FindForm().Top;
            int left = this.FindForm().Left;
            if ((point.X <= left + resizeBorderThickness + 4 && point.Y <= top + resizeBorderThickness + 4) || (point.X >= left + Width - resizeBorderThickness - 6 && point.Y >= top + Height - resizeBorderThickness - 6))
                return Cursors.SizeNWSE;
            else if ((point.X <= left + resizeBorderThickness + 4 && point.Y >= top + Height - resizeBorderThickness - 6) || (point.X >= left + Width - resizeBorderThickness - 6 && point.Y <= top + resizeBorderThickness + 4))
                return Cursors.SizeNESW;
            else if (point.X >= left + Width - 2 - resizeBorderThickness || point.X <= left + resizeBorderThickness)
                return Cursors.SizeWE;
            else if (point.Y >= top + Height - 2 - resizeBorderThickness || point.Y <= top + resizeBorderThickness)
                return Cursors.SizeNS;
            else
                return Cursors.Arrow;
        }

        /// <summary>
        /// 设置鼠标形状
        /// </summary>
        private void SetCursor()
        {
            this.FindForm().Cursor = CheckCursorType(Functions.GetMousePosition());
        }


        #endregion


    }
}